package com.android.volley.socket;

import android.text.TextUtils;
import android.util.Log;

import com.android.volley.BuildConfig;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.Socket;

import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;

/**
 * Created by yinzhiqun on 2015/8/31.
 * 处理ip地址切换
 */
public class SocketAddressSwitcher {
    private String mConfigPath;
    private volatile int timeoutCount;//连接超时次数
    private ServerAddress currentServerAddress;

    public SocketAddressSwitcher(String configPath) {
        mConfigPath = configPath;
        currentServerAddress = getServerAddressFromConfig();
    }

    public void onSocketTimeout() {
        if (++timeoutCount % 3 == 0) {//连接超时，多于5次，就开始获取新的业务服务器地址
            updateServerAddress();
        }
    }

    public ServerAddress getServerAddress() {
//        Log.i("kids",currentServerAddress.ip+" : "+currentServerAddress.port);
        return currentServerAddress;
    }

    /**
     * 更新业务服务器ip端口
     */
    public void updateServerAddress() {
        ServerAddress serverAddress = getServerAddressFromDNS();
        if (serverAddress != null) {
//            if (!currentServerAddress.ip.equals(serverAddress.ip) || currentServerAddress.port != serverAddress.port) {//新获取的地址和现在的地址不一样，才需要进行更新操作
            if (!TextUtils.isEmpty(serverAddress.ip) && !TextUtils.isEmpty(serverAddress.weather_ip) && serverAddress.port != 0 && serverAddress.weather_port != 0) {//新获取的地址和现在的地址不一样，才需要进行更新操作
                currentServerAddress = serverAddress;
                synchronized (SocketAddressSwitcher.class) {
                    try {
                        BufferedWriter writer = new BufferedWriter(new FileWriter(mConfigPath));
                        writer.write(serverAddress.ip);
                        writer.newLine();
                        writer.write(serverAddress.port + "");
                        writer.newLine();
                        writer.write(serverAddress.weather_ip + "");
                        writer.newLine();
                        writer.write(serverAddress.weather_port + "");
                        writer.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 获取本地保存的业务服务器ip端口
     *
     * @return
     */
    private ServerAddress getServerAddressFromConfig() {
        File config = new File(mConfigPath);
        if (config.exists()) {//如果更新过ip，才会有server_config文件
            synchronized (SocketAddressSwitcher.class) {
                try {
                    BufferedReader reader = new BufferedReader(new FileReader(config));
                    String ip = reader.readLine();
                    int port = Integer.parseInt(reader.readLine());
                    String weather_ip = reader.readLine();
                    int weather_port = Integer.parseInt(reader.readLine());
                    reader.close();

                    return new ServerAddress(ip, port, weather_ip, weather_port);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return new ServerAddress(BuildConfig.IP, BuildConfig.PORT, "", 0);//获取失败的话，还是使用默认ip地址
    }


    /**
     * 连门服务器，获取最新的业务服务器地址
     *
     * @return
     */
    private ServerAddress getServerAddressFromDNS() {
        try {
//            if (BuildConfig.DEBUG){
//                Log.i("kids","获取服务器ip");
//            }
            byte[] bytes = ("{\"cmd\":\"getserviceip\",\"channel\":\"" + BuildConfig.CHANNEL + "\"}").getBytes();

            Socket socket = new Socket(BuildConfig.IP, BuildConfig.PORT);
            socket.setSoTimeout(10000);
            BufferedSink bufferedSink = Okio.buffer(Okio.sink(socket.getOutputStream()));
            bufferedSink.writeInt(bytes.length);
            bufferedSink.write(bytes);
            bufferedSink.flush();
            BufferedSource bufferedSource = Okio.buffer(Okio.source(socket.getInputStream()));
            int len = bufferedSource.readInt();
            byte[] receive = bufferedSource.readByteArray(len);
            socket.close();

            String s = new String(receive);
//            if (BuildConfig.DEBUG){
            Log.i("kids", s);
//            }

            JSONObject result = new JSONObject(s).optJSONObject("result");
            String ip = result.optString("ip");
            int port = result.optInt("port");
            String weather_ip = result.optString("weather_ip");
            int weather_port = result.optInt("weather_port");

            return new ServerAddress(ip, port, weather_ip, weather_port);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
